/*
 * Copyright 2011 Dominik Pretzsch <dominik.pretzsch at gmail.com>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.blacksheep.jmoteextract.mvc.model;

import de.blacksheep.jmoteextract.component.Job;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Dominik Pretzsch <dominik.pretzsch at gmail.com>
 */
public class JobTableModel extends DefaultTableModel {
    
    private String[] columnNames;
    //private ArrayList<Job> jobs;
    private ArrayList<Integer> rows;
    private ConcurrentHashMap<Integer, Job> jobsMap;
    
    public static final int COL_FILENAME = 0;
    public static final int COL_FILEPATH = 1;
    public static final int COL_PROGRESS = 2;
    
    public JobTableModel() {
        maybeInit();
    }
    
    private void maybeInit() {
        if (columnNames == null) {
            // TODO: I18N
            columnNames = new String[] {"Dateiname", "Pfad", "Fortschritt"};
            this.setColumnIdentifiers(columnNames);
        }
        /*if (jobs == null) {
            jobs = new ArrayList<Job>();
        }*/
        if (rows == null) {
            rows = new ArrayList<Integer>();
        }
        if (jobsMap == null) {
            jobsMap = new ConcurrentHashMap<Integer, Job>();
        }
    }
    
    public synchronized int addJob(Job job) {        
        jobsMap.put(job.getHash(), job);
        rows.add(job.getHash());        
        //jobs.add(job);
        fireTableDataChanged();
        //return jobs.size() - 1;
        //return rows.size() - 1;
        return getRowFromHash(job.getHash());
    }
    
    public synchronized int addJob(int hash, String fileName, String filePath) {        
        Job job = new Job();
        job.setFileName(fileName);
        job.setFilePath(filePath);
        job.setHash(hash);        
        return addJob(job);
    }
    
    public synchronized void setFileName(int hash, String fileName) {
        //Job job = jobs.get(row);
        //int hash = rows.get(row);
        Job job = jobsMap.get(hash);
        job.setFileName(fileName);
        fireTableCellUpdated(getRowFromHash(hash), COL_FILENAME);
    }
    
    public synchronized String getFileName(int hash) {
        Job job = jobsMap.get(hash);
        return job.getFileName();
    }
    
    public synchronized void setFilePath(int hash, String filePath) {
        //Job job = jobs.get(row);
        //int hash = rows.get(row);
        Job job = jobsMap.get(hash);
        job.setFilePath(filePath);
        fireTableCellUpdated(getRowFromHash(hash), COL_FILEPATH);
    }
    
    public synchronized String getFilePath(int hash) {
        Job job = jobsMap.get(hash);
        return job.getFilePath();
    }
    
    public synchronized void setProgress(int hash, int percent) {
        //Job job = jobs.get(row);
        //int hash = rows.get(row);
        Job job = jobsMap.get(hash);
        job.setProgress(percent);
        fireTableCellUpdated(getRowFromHash(hash), COL_PROGRESS);
    }
    
    public synchronized int getProgress(int hash) {
        Job job = jobsMap.get(hash);
        return job.getProgress();
    }
    
    @Override
    public boolean isCellEditable(int row, int col) {
        return false;
    }
    
    @Override
    public int getColumnCount() {
        // Work-around NullPointerException
        maybeInit();
        return columnNames.length;
    }
    
    @Override
    public String getColumnName(int col) {
        // Work-around NullPointerException
        maybeInit();
        return columnNames[col];
    }
    
    @Override
    public int getRowCount() {
        // Work-around NullPointerException
        maybeInit();
        //return jobs.size();
        return rows.size();
    }
    
    @Override
    public Object getValueAt(int row, int col) {
        //Job job = jobs.get(row);
        int hash = rows.get(row);
        //Job job = jobsMap.get(hash);
        switch (col) {
            case COL_FILENAME:
                return getFileName(hash);
            case COL_FILEPATH:
                return getFilePath(hash);
            case COL_PROGRESS:
                return getProgress(hash);
            default:
                return null;
        }
    }
    
    @Override
    public void setValueAt(Object value, int row, int col) {
        //Job job = jobs.get(row);
        int hash = rows.get(row);
        //Job job = jobsMap.get(hash);
        switch (col) {
            case COL_FILENAME:
                setFileName(hash, (String) value);
            case COL_FILEPATH:
                setFilePath(hash, (String) value);
            case COL_PROGRESS:
                setProgress(hash, (Integer) value);
        }
        //fireTableCellUpdated(row, col);
    }
    
    @Override
    public void removeRow(int row) {
        removeRowSync(row);
    }
    
    private synchronized void removeRowSync(int row) {
        int hash = rows.get(row);
        rows.remove(row);
        jobsMap.remove(hash);
        fireTableDataChanged();
    }
    
    public synchronized void removeRowByHash(int hash) {
        int row = getRowFromHash(hash);
        removeRow(row);
    }
    
    public synchronized int getRowFromHash(int hash) {
        return rows.indexOf(hash);
    }
}
